package com.saver.view.dialog;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.saver.R;
import com.saver.core.domain.Banco;
import com.saver.core.domain.Categoria;
import com.saver.core.domain.CategoriaEquiv;
import com.saver.core.domain.Establecimiento;
import com.saver.core.domain.EstablecimientoEquiv;
import com.saver.core.domain.Transaccion;
import com.saver.core.persistence.DBManager;
import com.saver.core.persistence.EstablecimientoRestService;
import com.saver.core.persistence.bean.ItemEstablecimiento;
import com.saver.core.processor.EstadoTransaccion;
import com.saver.core.processor.TipoRegistro;
import com.saver.core.processor.TipoToken;
import com.saver.core.processor.util.Util;
import com.saver.core.util.Constantes;
import com.saver.core.util.DateUtil;
import com.saver.view.adapter.PlacesAutoCompleteAdapter;
import com.saver.view.adapter.ResetAutoComplete;
import com.saver.view.gui.ButtonFecha;

/**
 * Created by HeRGoS on 18/04/2015
 */
public class EditTransactionDialog extends DialogFragment implements ResetAutoComplete, View.OnClickListener {

    private static final String TAG = "EditTransactionDialog";

    private Transaccion transaccion;
    private View view;
    private Spinner categoria;
    private Spinner banco;
    private EditText monto;
    private AutoCompleteTextView establecimiento;
    private ButtonFecha buttonFecha;
    private List<Categoria> categorias;
    private ItemEstablecimiento itemEstablecimiento;
    private RefreshActivity activity;
    private EditText estEquivText;

    private Map<Integer, Boolean> enables = new HashMap<Integer, Boolean>();

    public void setTransaccionID(Integer transaccionID) {
        transaccion = DBManager.transaccionSQLite().buscarPorId(transaccionID);
    }

    public void setButtonEnabled(int whichButton, boolean enabled) {
        enables.put(whichButton, enabled);
    }

    public void setParent(RefreshActivity activity) {
        this.activity = activity;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        setCancelable(false);
        view = LayoutInflater.from(getActivity()).inflate(R.layout.activity_editar_transaccion, null);
        iniciarBancos();
        iniciarCategorias();
        iniciarEstablecimiento();
        iniciarMonto();
        iniciarFecha();
        final AlertDialog dialog = new AlertDialog.Builder(getActivity())
                .setView(view)
                .setNegativeButton("Eliminar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {}
                })
                .setNeutralButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {}
                })
                .setPositiveButton("Guardar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {}
                })
                .create();
        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }

    @Override
    public void onStart() {
        super.onStart();
        AlertDialog dialog = (AlertDialog) getDialog();
        for (Map.Entry<Integer, Boolean> enable : enables.entrySet()) {
            Button button = dialog.getButton(enable.getKey().intValue());
            button.setEnabled(enable.getValue().booleanValue());
        }

        dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                eliminarTransaccion();
            }
        });

        dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean response = grabarTransaccion();
                Log.d(TAG, "response: " + response);
                if (response) {
                    Log.d(TAG, "activity: " + activity.getClass());
                    activity.refresh(buttonFecha.getFecha().toString());
                    dismiss();
                }
            }
        });
    }

    private void iniciarBancos() {
        ArrayList<Item> itemsBanco = new ArrayList<Item>();
        int bancoSel = -1;
        Integer idBanco = transaccion == null ? null : transaccion.getIdBanco();
        Log.d(TAG, "idBanco: " + idBanco);
        List<Banco> bancos = DBManager.bancoSQLite().buscarTodoActivo();
        for (int i = 0, n = bancos.size(); i < n; i++) {
            Banco b = bancos.get(i);
            itemsBanco.add(new Item(b.getId(), b.getNombre()));
            if (b.getId().equals(idBanco)) {
                bancoSel = i;
            }
        }

        banco = (Spinner) view.findViewById(R.id.banco);
        banco.setBackgroundColor(Color.parseColor("#9370DB") & 0x60FFFFFF);
//        banco.setAdapter(new ArrayAdapter<Item>(view.getContext(), android.R.layout.simple_spinner_item, itemsBanco));
        banco.setAdapter(new BancoSpinnerAdapter(view.getContext(), android.R.layout.simple_spinner_item, bancos.toArray(new Banco[0])));
        if (bancoSel >= 0) {
            banco.setSelection(bancoSel);
        }
    }

    private void iniciarCategorias() {
        Integer categoriaID = transaccion == null ? null : transaccion.getIdCategoria();
        Log.d(TAG, "CategoriaID: " + categoriaID);
        categorias = DBManager.categoriaSQLite().buscarTodo();

        categoria = (Spinner) view.findViewById(R.id.categoria);
        categoria.setAdapter(new CategoriaSpinerAdapter(view.getContext(), 
        					 android.R.layout.simple_spinner_item, 
        					 categorias.toArray(new Categoria[0])));
        categoria.setSelection(getIndiceCategoria(categoriaID));
    }

    private void iniciarEstablecimiento() {
        EstablecimientoRestService establecimientoRestService = new EstablecimientoRestService();
        establecimiento = (AutoCompleteTextView) view.findViewById(R.id.establecimiento);
        establecimiento.setAdapter(new PlacesAutoCompleteAdapter(view.getContext(), R.layout.item_establecimiento,
                DBManager.establecimientoSQLite(), establecimientoRestService, this));
        Integer idEstablecimiento = transaccion == null ? null : transaccion.getIdEstablecimiento();
        Log.d(TAG, "idEstablecimiento: " + idEstablecimiento);
        if (idEstablecimiento != null) {
            Establecimiento estab = DBManager.establecimientoSQLite().buscarPorId(idEstablecimiento);
            Log.d(TAG, "establecimiento: " + establecimiento);
            Log.d(TAG, "estab: " + estab);
            establecimiento.setText(estab.getNombre());
        }
        establecimiento.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Object item = parent.getItemAtPosition(position);
                seleccionarEstablecimiento((ItemEstablecimiento) item);
            }
        });
        
        String referencia = transaccion == null ? null : transaccion.getReferencia();
        estEquivText = (EditText) view.findViewById(R.id.nomEstablEquiv);
        
        if (Util.noEsVacio(referencia)) {
        	estEquivText.setHint("");
        	estEquivText.setText(referencia);
        	
        } else {
	        Integer idEstabEquiv = transaccion == null ? null : transaccion.getIdEstablecimientoEquiv();
	        Log.d(TAG, "idEstabEquiv: " + idEstabEquiv);
	        
	        if (idEstabEquiv != null) {
	            EstablecimientoEquiv establecimientoEquiv = DBManager.establecimientoEquivSQLite().buscarPorId(idEstabEquiv);
	            estEquivText.setHint(establecimientoEquiv.getNombre());
        		estEquivText.setText("");
        		Log.d(TAG, "establecimientoEquiv: " + establecimientoEquiv.getNombre());
	            
	        } else {
	        	Integer idCategoriaEquiv = transaccion == null ? null : transaccion.getIdCategoriaEquiv();
	        	Log.d(TAG, "idCategoriaEquiv: " + idCategoriaEquiv);
	        	
	        	if (idCategoriaEquiv != null) {
	        		CategoriaEquiv categoriaEquiv = DBManager.categoriaEquivSQLite().buscarPorId(idCategoriaEquiv);
	        		estEquivText.setHint(categoriaEquiv.getNombre());
	        		estEquivText.setText("");
	        		Log.d(TAG, "categoriaEquiv: " + categoriaEquiv.getNombre());
	        		
	        	} else {
	        		estEquivText.setText("");
	        	}
	        }
	    	
	    }
    }

    private void iniciarMonto() {
        monto = (EditText) view.findViewById(R.id.monto);
        Typeface typeface = Typeface.createFromAsset(getActivity().getAssets(), "DS-DIGIB.TTF");
        monto.setTypeface(typeface);
        if (transaccion != null && transaccion.getMonto() != null) {
            Log.d(TAG, "Monto: " + transaccion.getMonto());
            monto.setText(String.valueOf(transaccion.getMonto()));
        }
    }

    private void iniciarFecha() {
        buttonFecha = (ButtonFecha) view.findViewById(R.id.button_fecha);
        buttonFecha.setBackgroundColor(Color.parseColor("#9370DB"));
        Date fecha;
        if (transaccion == null) {
            fecha = new Date();
        } else {
            fecha = new Date(transaccion.getFechaTransaccion());
        }
        buttonFecha.setFecha(DateUtil.FORMATO_GENERAL.format(fecha));
        buttonFecha.setClickable(true);
        buttonFecha.setOnClickListener(this);
    }

    private int getIndiceCategoria(Integer idCategoria) {
        Log.d(TAG, "idCategoria: " + idCategoria);
        if (idCategoria == null) {
            idCategoria = 1; // otros
        }
        int categoriaSel = -1;
        for (int i = 0, n = categorias.size(); i < n; i++) {
            Categoria c = categorias.get(i);
            if (c.getId().equals(idCategoria)) {
                categoriaSel = i;
            }
        }
        Log.d(TAG, "categoriaSel: " + categoriaSel);
        if (categoriaSel >= 0) {
            return categoriaSel;
        }
        return 1;
    }

    private void seleccionarEstablecimiento(ItemEstablecimiento item) {
        itemEstablecimiento = item;
        Log.d(TAG, "item: " + item);
        categoria.setSelection(getIndiceCategoria(item.getIdCatServ()));
    }

    @Override
    public void reset() {
        System.out.println("reset");
        itemEstablecimiento = null;
    }

    @Override
    public void onClick(View v) {
        if (v instanceof ImageButton) {
            Calendar calendar = Calendar.getInstance();
            int anio, mes, dia;
            try {
                calendar.setTimeInMillis(DateUtil.FORMATO_GENERAL.parse(buttonFecha.getFecha().toString()).getTime());
            } catch (Exception e) {
                Log.e(TAG, "error de parseo", e);
            }
            anio = calendar.get(Calendar.YEAR);
            mes = calendar.get(Calendar.MONTH);
            dia = calendar.get(Calendar.DAY_OF_MONTH);
            DatePickerDialog dpd = new DatePickerDialog(view.getContext(), new DatePickerDialog.OnDateSetListener() {

                @Override
                public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                    buttonFecha.setFecha(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year);

                }
            }, anio, mes, dia);
            dpd.getDatePicker().setMaxDate(new Date().getTime());
            dpd.show();
        }
    }

    private void eliminarTransaccion() {
    	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        eliminar();
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("\u00BFUsted est\u00E1 seguro de eliminar el registro?").setPositiveButton("Si", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    }

    public void eliminar() {
        DBManager.transaccionSQLite().eliminar(transaccion);
        activity.refresh(null);
        dismiss();
    }

    private boolean grabarTransaccion() {
        Log.d(TAG, "grabarTransaccion");

        if (transaccion == null) {
            Log.d(TAG, "nuevo");
            transaccion = new Transaccion();
            transaccion.setEstado(EstadoTransaccion.NUEVO.getValor());
            
        } else if (transaccion.getId() == null) {
            transaccion.setEstado(EstadoTransaccion.NUEVO.getValor());
            
        } else {
            Log.d(TAG, "actualizar");
            transaccion.setEstado(EstadoTransaccion.ACTUALIZADO.getValor());
        }
        Log.d(TAG, "idTransaccion: " + transaccion.getId());

        transaccion.setTipo(TipoToken.EGRESO.getId());
        transaccion.setRevisado(Constantes.TRANSACCION_REVISADA);

        Banco itemBanco = (Banco) banco.getSelectedItem();
        Log.d(TAG, "itemBanco: " + itemBanco);
        transaccion.setIdBanco(itemBanco.getId());

        Categoria itemCategoria = (Categoria) categoria.getSelectedItem();
        Log.d(TAG, "itemCategoria: " + itemCategoria);
        transaccion.setIdCategoria(itemCategoria.getId());

        String strMonto = monto.getText().toString();
        double valMonto = Util.esVacio(strMonto) ? 0 : Double.parseDouble(strMonto);
        Log.d(TAG, "valMonto: " + valMonto);
        if (valMonto <= 0) {
            Toast.makeText(getActivity(), "El monto debe ser mayor a cero", Toast.LENGTH_LONG).show();
            return false;
        }
        transaccion.setMonto(valMonto);

        Log.d(TAG, "itemEstablecimiento: " + itemEstablecimiento);
        // ha seleccionado un establecimiento
        if (itemEstablecimiento != null) {
            Establecimiento establecimiento = DBManager.establecimientoSQLite().buscarPorIdServidor(itemEstablecimiento.getIdServ());
            if (establecimiento == null) {
            	establecimiento = new Establecimiento();
            	establecimiento.setIdCategoria(itemEstablecimiento.getIdCatServ());
            	establecimiento.setIdServidor(itemEstablecimiento.getIdServ());
            	establecimiento.setNombre(itemEstablecimiento.getNombre());
            	establecimiento.setTipo(itemEstablecimiento.getTipoRegistro());
            	
            	DBManager.establecimientoSQLite().guardar(establecimiento);
            }
            
            transaccion.setIdEstablecimiento(establecimiento.getIdEstablecimiento());

        } else {
            String texto = establecimiento.getText().toString();
            if (Util.noEsVacio(texto)) {
                Establecimiento establecimiento = new Establecimiento();
                establecimiento.setIdCategoria(itemCategoria.getId());
                establecimiento.setIdServidor(null);
                establecimiento.setNombre(texto.trim());
                establecimiento.setTipo(TipoRegistro.USUARIO.getValor());

                DBManager.establecimientoSQLite().guardar(establecimiento);

                transaccion.setIdEstablecimiento(establecimiento.getIdEstablecimiento());
            }
        }

        try {
            Date date = DateUtil.FORMATO_GENERAL.parse(buttonFecha.getFecha().toString());
            transaccion.setFechaTransaccion(date.getTime());
            transaccion.setFechaText(Util.getStringToDateTime(date));
        } catch (ParseException e) {
            Log.d(TAG, "error de parseo", e);
        }

        transaccion.setIdCategoria(itemCategoria.getId());
        
        transaccion.setReferencia(estEquivText.getText().toString());

        if (EstadoTransaccion.NUEVO.getValor() == transaccion.getEstado().shortValue()) {
            DBManager.transaccionSQLite().guardar(transaccion);
        } else {
            DBManager.transaccionSQLite().actualizar(transaccion);
        }
        return true;
    }

    private class Item {

        private Integer id;
        private String texto;

        public Item(Integer id, String texto) {
            this.id = id;
            this.texto = texto;
        }

        public Integer getId() {
            return id;
        }

        public String getTexto() {
            return texto;
        }

        @Override
        public String toString() {
            return getTexto();
        }
    }
}
